package com.haitai.solr.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

public class HttpclientTools implements Serializable {

    private static final long serialVersionUID = 4634161754990919271L;

    private static volatile HttpClient httpClient;

    private HttpclientTools(){}


    /**
     * GET 方式请求
     * 参数通过 url 拼接
     *
     * @param host 请求地址
     * @param path 接口路径
     * @param paramsMap 请求参数
     * @return
     * @throws IOException
     */
    public static HttpResponse doGet(String host, String path, Map<String, String> paramsMap) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpGet httpGet = new HttpGet(getRequestUrl(host, path, paramsMap));
        httpGet.setConfig(requestConfig);
        httpGet.setHeader(HTTP.CONTENT_TYPE,ContentType.create(ContentType.APPLICATION_FORM_URLENCODED
                .getMimeType(),Consts.UTF_8).toString());

        return httpClient.execute(httpGet);
    }
    
    /**
     * GET 方式请求
     * 参数通过 url 拼接
     *
     * @return
     * @throws IOException
     * @throws URISyntaxException 
     */
    public static HttpResponse doGet(String url) throws Exception {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        //HttpGet httpGet = new HttpGet(getRequestUrl(host, path, paramsMap));
        URL urlurl = new URL(url);
        URI uri = new URI("http",urlurl.getUserInfo(),urlurl.getHost(),urlurl.getPort(),urlurl.getPath(),urlurl.getQuery(),null);
        HttpGet httpGet = new HttpGet(uri);
        httpGet.setConfig(requestConfig);
        httpGet.setHeader(HTTP.CONTENT_TYPE,ContentType.create(ContentType.APPLICATION_FORM_URLENCODED
                .getMimeType(),Consts.UTF_8).toString());

        return httpClient.execute(httpGet);
    }

    /**
     * POST 方式请求
     * 参数通过 url 拼接
     *
     * @param host 请求地址
     * @param path 接口路径
     * @param paramsMap 请求参数
     * @return
     * @throws IOException
     */
    public static HttpResponse doPost(String host, String path, Map<String, String> paramsMap) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpPost httpPost = new HttpPost(getRequestUrl(host, path, paramsMap));
        httpPost.setConfig(requestConfig);
        httpPost.setHeader(HTTP.CONTENT_TYPE,ContentType.create(ContentType.APPLICATION_FORM_URLENCODED
                .getMimeType(),Consts.UTF_8).toString());

        return httpClient.execute(httpPost);
    }
    
    /**
     * POST 方式请求
     * 参数通过 Body 传送,JSON 格式
     *
     * @param path 接口路径
     * @param indexJson 请求参数(json 字符串)
     * @param coreName 请求参数(core的名称)
     * @param status 请求参数(查询或者添加索引的状态)
     * @return
     */
    public static String doPost(String path, String indexJson,String coreName,String status) throws IOException {
    	HttpPost httpPost = new HttpPost(path);
    	String responseContent;
    	try{
    		CloseableHttpClient client = HttpClients.createDefault();
    		List<NameValuePair> params = new ArrayList<NameValuePair>();
    		if(status.equals("create")) {
    			params.add(new BasicNameValuePair("indexJson", indexJson));
    		}else if(status.equals("query")) {
    			params.add(new BasicNameValuePair("queryJson", indexJson));
    		}else if(status.equals("update")) {
    			params.add(new BasicNameValuePair("updateJson", indexJson));
    		}
    		params.add(new BasicNameValuePair("coreName", coreName));
    		HttpEntity entity = new UrlEncodedFormEntity(params,"UTF-8");
    		httpPost.setEntity(entity);
    		CloseableHttpResponse response = client.execute(httpPost);
    		System.out.println("response Code: " +status+ response.getStatusLine().getStatusCode());
			 responseContent = EntityUtils.toString(response.getEntity(),"utf-8");
//			 System.out.println(responseContent);
    		
    	}finally{
    		httpPost.releaseConnection();
    	}
    	return responseContent;

    }

    /**
     * POST 方式请求
     * 参数通过 Body 传送,JSON 格式
     *
     * @param host 请求地址
     * @param path 接口路径
     * @param jsonParams 请求参数(json 字符串)
     * @return
     */
    public static HttpResponse doPost22222(String host, String path, String jsonParams) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpPost httpPost = new HttpPost(host + path);
        StringEntity stringentity = new StringEntity(jsonParams, ContentType.APPLICATION_JSON);
        httpPost.setEntity(stringentity);
        httpPost.setConfig(requestConfig);
        httpPost.addHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());

        return httpClient.execute(httpPost);
    }

    /**
     * POST 方式请求
     * 文件上传
     *
     * @param host 请求地址
     * @param path 接口路径
     * @param paramsMap 请求参数
     * @param fileInputStream 待上传文件流
     * @param name 文件对应字段名
     * @param fileOriginalName 原始文件名
     * @return
     */
    public static HttpResponse doPost(String host, String path, Map<String, String> paramsMap,
                                      InputStream fileInputStream, String name, String fileOriginalName) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpPost httpPost = new HttpPost(host + path);
        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
        // 解决中文文件名乱码问题
        entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        entityBuilder.setCharset(Consts.UTF_8);
        ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), Consts.UTF_8);
        for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
            entityBuilder.addTextBody(entry.getKey(), entry.getValue(), contentType);
        }
        if (fileInputStream != null && name != null && fileOriginalName != null) {
            entityBuilder.addBinaryBody(name, fileInputStream, ContentType.DEFAULT_BINARY, fileOriginalName);
        }
        httpPost.setEntity(entityBuilder.build());
        httpPost.setConfig(requestConfig);

        return httpClient.execute(httpPost);
    }



    /**
     * 初始化 httpClient
     * @return
     */
    private static HttpClient initHttpClient() {
        if  (httpClient == null) {
            synchronized (HttpClient.class) {
                if (httpClient == null) {
                    httpClient = HttpClients.createDefault();
                }
            }
        }
        return httpClient;
    }

    /**
     * 获取完整请求地址(包含参数)
     * 参数拼接在 url 中
     *
     * @param host 请求地址
     * @param path 接口路径
     * @param paramsMap 请求参数
     * @return
     */
    private static String getRequestUrl(String host, String path, Map<String, String> paramsMap) {
        StringBuilder reqUrl = new StringBuilder(host).append(path);
        if (paramsMap != null && !paramsMap.isEmpty()) {
            StringBuilder params = new StringBuilder();
            for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                params.append("&" + entry.getKey() + "=" + entry.getValue());
            }
            String paramConnector = "?";
            if (!host.contains(paramConnector) && !path.contains(paramConnector)) {
                reqUrl.append(paramConnector);
                reqUrl.append(params.toString().substring(1));
            } else {
                reqUrl.append(params.toString());
            }
        }

        return reqUrl.toString();
    }
    
	/**
	 * get请求通用客户端
	 * @param url
	 * 		请求地址
	 * @param paramMap
	 * 		传递参数
	 * @return
	 */
	public static String amget(String url, HashMap<String, String> paramMap) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		String result = null;

		try {
			// 1.创建HttpClient对象

			httpClient = HttpClients.createDefault();
			RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
					.setConnectionRequestTimeout(1000).setSocketTimeout(5000).build();
			// 2.创建uri
			URIBuilder uriBuilder = new URIBuilder(url);
			if (paramMap != null && !paramMap.isEmpty()) {
				for (String key : paramMap.keySet()) {
					uriBuilder.addParameter(key, paramMap.get(key));
				}
			}
			URI uri = uriBuilder.build();

			// 3.创建httpGet

			HttpGet httpGet = new HttpGet(uri);

			// 4.发送http请求
			response = httpClient.execute(httpGet);
			// 相应返回值
			if (response != null && response.getStatusLine().getStatusCode() == 200) {
				result = EntityUtils.toString(response.getEntity(), "utf-8");
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				httpClient.close();
				if (response != null) {
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return result;

	}
	
    	public static String ampost(String path, HashMap<String, String> paramMap) throws IOException {
    	HttpPost httpPost = new HttpPost(path);
    	String responseContent;
    	try{
    		CloseableHttpClient client = HttpClients.createDefault();
    		List<NameValuePair> params = new ArrayList<NameValuePair>();
    		for (String key : paramMap.keySet()) {
    			params.add(new BasicNameValuePair(key, paramMap.get(key)));
			}
    		HttpEntity entity = new UrlEncodedFormEntity(params,"UTF-8");
    		httpPost.setEntity(entity);
    		CloseableHttpResponse response = client.execute(httpPost);
//    		System.out.println("response Code: " +status+ response.getStatusLine().getStatusCode());
			 responseContent = EntityUtils.toString(response.getEntity(),"utf-8");
//			 System.out.println(responseContent);
    		
    	}finally{
    		httpPost.releaseConnection();
    	}
    	return responseContent;

    }
    
}
